﻿package igz.fleaxy.ui.scrollbar
{
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.LineScaleMode;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	import igz.fleaxy.util.ObjectUtil;
	import igz.fleaxy.util.SpriteUtil;

	/**
	 * @author Intelygenz | www.intelygenz.com
	 */
	public class ScrollContainerUi extends Sprite {
		
		private var _Settings	: Object;
		
		private var _Bg			: Sprite;
		protected var _Container	: Sprite;
		public function get $Container (): Sprite {
			return _Container;
		}
		
		public function get $Settings () : Object {
			return _Settings;
		}
		
		public function set $Settings ( p_settings:Object ) : void {
			ObjectUtil.$Merge( p_settings, _Settings );
			_Refresh();
		}
		
		/**
		 * Proporciona un contenedor que ofrece todos los servicios necesarios
		 * para realizar scroll sobre su contenido.
		 *
		 * @param	p_settings { width : 100
		 * 					   , height: 100
		 *					   , background : 0xFFFFFF
		 *				   	   , backgroundAlpha : 1
		 *					   , autoscrollY : false
		 *					   , border : null
		 * 						}
		 */
		public function ScrollContainerUi( p_settings:Object = null ) {
			_Settings = { "width":  100
						, "height": 100
						, "background": 0xFFFFFF
						, "backgroundAlpha": 1
						, "autoscrollY" : false
						, "border" : null
						, "borderThickness" : 0
						, "borderAlpha" : 1
						}

			ObjectUtil.$Merge( p_settings, _Settings );


			_Bg = new Sprite();
			super.addChild( _Bg );
			
			_Container = new Sprite();
			super.addChild( _Container );
			
			_Refresh();
			
			$Clear();
		}

		
		private function _AutoscrollY ( p_event:Event ) : void {
			if ( _Container.height > height ) {
				_Container.y = -(_Container.height - height);
			}
		}

		private function _Refresh():void {
			if ( _Settings["autoscrollY"] ) {
				this.addEventListener( Event.CHANGE, _AutoscrollY );
			}
			_CreateScrollRect();
			_DrawBg();
		}
		
		private function _CreateScrollRect():void {
			this.scrollRect = new Rectangle(0, 0, _Settings["width"], _Settings["height"]);
		}

		private function _DrawBg():void {
			if ( _Settings["background"] is Bitmap ) {
				SpriteUtil.$RemoveChildsOf( _Bg );
				_Bg.addChild( _Settings["background"] as Bitmap );
			}
			else {
				_Bg.graphics.clear();
				
				var marginBorder : Number = 0;
				if ( _Settings["border"] != null ) {
					marginBorder = _Settings["borderThickness"] / 2;
					_Bg.graphics.lineStyle( _Settings["borderThickness"], _Settings["border"], _Settings["borderAlpha"], true );
				}
				
				_Bg.graphics.beginFill( _Settings["background"], _Settings["backgroundAlpha"] );
				_Bg.graphics.drawRect(marginBorder
									, marginBorder
									, _Settings["width"] - _Settings["borderThickness"]
									, _Settings["height"] - _Settings["borderThickness"]
									);
				_Bg.graphics.endFill();
			}
		}
		
		public function $Draw(p_setting:Object = null):void {
			ObjectUtil.$Merge(p_setting, _Settings);
			_DrawBg();
		}

		public function $Clear() : void {
			SpriteUtil.$RemoveChildsOf( _Container );

			var pixelZero:Sprite = new Sprite();
			pixelZero.graphics.beginFill(0x000000, 0);
			pixelZero.graphics.drawRect(0, 0, 1, 1);
			pixelZero.graphics.endFill();
			_Container.addChild( pixelZero );
			
			ObjectUtil.$CleanMemory();

			_RefreshScrollBars();
		}
		
		public function $RefreshScrollBars () : void {
			_RefreshScrollBars();
		}
		
		private function _RefreshScrollBars() : void {
			this.dispatchEvent( new Event(Event.CHANGE) );
		}

		override public function set width (p_width:Number) : void {
			if ( _Settings["width"] != p_width ) {
				_Settings["width"] = p_width;
				_Refresh();
				
				_RefreshScrollBars();
			}
		}
		
		override public function set height (p_height:Number) : void {
			if ( _Settings["height"] != p_height ) {
				_Settings["height"] = p_height;
				_Refresh();
				
				_RefreshScrollBars();
			}
		}
		
		override public function set x (p_x:Number) : void {
			super.x = p_x;
			_RefreshScrollBars();
		}
		
		override public function set y (p_y:Number) : void {
			super.y = p_y;
			_RefreshScrollBars();
		}

		override public function addChild(p_child:DisplayObject):DisplayObject {
			_Container.addChild(p_child);
			_DrawBg();

			_RefreshScrollBars();
			return p_child;
		}
		
		override public function removeChild(p_child:DisplayObject):DisplayObject {
			_Container.removeChild(p_child);

			_RefreshScrollBars();
			return p_child;
		}
		
		override public function get width():Number {
			return _Settings["width"];
		}
		
		override public function get height():Number {
			return _Settings["height"];
		}
		/*
		 * Parece que _Container.height no funciona correctamente:
		 * si tenemos un objeto en y=1000 y lo borramos sigue devolviendonos la misma altura
		 * Probar!!!
		 * 
		public function get $HeightContainer():Number {
			var heightContainer:Number = 0;
			var displayObject:DisplayObject;
			var i:int;
			trace("Container " + _Container.numChildren);
			if (_Container != null) {
				for ( i = 0; i < _Container.numChildren; i++) {
					if (_Container.getChildAt(i) is DisplayObject) {
						displayObject = _Container.getChildAt(i)
						if ((displayObject.y + displayObject.height) > heightContainer) {
							//trace(_Container[i].y);
							heightContainer = displayObject.y + displayObject.height;
						//}
					}
					}
				}
			}
			
			
			return heightContainer;
		}*/
	}
}